using System.Web.Mvc;
using ETestIT.Core;
using ETestIT.Core.Infrastructure;
using SharpArch.Core.PersistenceSupport;
using SharpArch.Core.DomainModel;
using System.Collections.Generic;
using System;
using SharpArch.Web.NHibernate;
using NHibernate.Validator.Engine;
using System.Text;
using SharpArch.Web.CommonValidator;
using SharpArch.Core;

namespace ETestIT.Web.Controllers
{
    [HandleError]
    public class PositionsController : Controller
    {
        const string Message = "A {0} for {1} is already present. Try to increase number of openings.";

        public PositionsController(
            IRepository<Position> positionRepository, 
            IRepository<JobTitle> jobTitlesRepository,
            IRepository<Client> clinetRepository)
        {
            Check.Require(positionRepository != null, "positionRepository may not be null");

            this.positionRepository = positionRepository;
            this.jobTitlesRepository = jobTitlesRepository;
            this.clinetRepository = clinetRepository;
        }

        [Transaction]
        public ActionResult Index() {
            IList<Position> positions = positionRepository.GetAll();
            return View(positions);
        }

        [Transaction]
        public ActionResult Show(int id) {
            Position position = positionRepository.Get(id);
            return View(position);
        }

        public ActionResult Create() {
            PositionFormViewModel viewModel = PositionFormViewModel.CreatePositionFormViewModel(jobTitlesRepository, clinetRepository);
            return View(viewModel);
        }

        private bool DashboardCellForThisPositionIsEmpty(Position position)
        {
            var reasult = true;
            var positions = positionRepository.GetAll();

            positions.ForEach(x => {
                  if ((x.TheJobTitle == position.TheJobTitle) && 
                      (x.TheComapny == position.TheComapny) &&
                      (x.Id != position.Id))
                      reasult = false;
              });

            return reasult;
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(Position position) {
            if (ViewData.ModelState.IsValid && position.IsValid()) {

                if (DashboardCellForThisPositionIsEmpty(position))
                {
                    positionRepository.SaveOrUpdate(position);

                    TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] =
                        "The position was successfully created.";
                    return RedirectToAction("Index");
                    
                }

                ThisPositionForCompanyOnDashBoardIsAlreadyPresentError(position);
            }

            PositionFormViewModel viewModel = PositionFormViewModel.CreatePositionFormViewModel(jobTitlesRepository, clinetRepository);
            viewModel.Position = position;
            return View(viewModel);
        }

        private void ThisPositionForCompanyOnDashBoardIsAlreadyPresentError(Position position)
        {
            ModelState.AddModelError("Error", string.Format(Message, position.TheJobTitle.Name, position.TheComapny.Name));
        }

        [Transaction]
        public ActionResult Edit(int id) {
            PositionFormViewModel viewModel = PositionFormViewModel.CreatePositionFormViewModel(jobTitlesRepository, clinetRepository);
            viewModel.Position = positionRepository.Get(id);
            return View(viewModel);
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(Position position) {
            Position positionToUpdate = positionRepository.Get(position.Id);
            TransferFormValuesTo(positionToUpdate, position);

            if (ViewData.ModelState.IsValid && position.IsValid()) {

                if (DashboardCellForThisPositionIsEmpty(position))
                {
                    TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] =
                        "The position was successfully updated.";
                    return RedirectToAction("Index");
                }

                ThisPositionForCompanyOnDashBoardIsAlreadyPresentError(position);
            }
            
            positionRepository.DbContext.RollbackTransaction();

            PositionFormViewModel viewModel = PositionFormViewModel.CreatePositionFormViewModel(jobTitlesRepository, clinetRepository);
            viewModel.Position = position;
            return View(viewModel);
        }

        private void TransferFormValuesTo(Position positionToUpdate, Position positionFromForm) {
			positionToUpdate.TheJobTitle = positionFromForm.TheJobTitle;
			positionToUpdate.TheComapny = positionFromForm.TheComapny;
			positionToUpdate.Duration = positionFromForm.Duration;
			positionToUpdate.KeySkills = positionFromForm.KeySkills;
			positionToUpdate.Location = positionFromForm.Location;
			positionToUpdate.Description = positionFromForm.Description;
			positionToUpdate.ThePosition = positionFromForm.ThePosition;
			
            positionToUpdate.IsStar = positionFromForm.IsStar;
            positionToUpdate.ExcelentCommunicationSkills = positionFromForm.ExcelentCommunicationSkills;
            positionToUpdate.Openings = positionFromForm.Openings;
            positionToUpdate.IsRemote = positionFromForm.IsRemote;
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Delete(int id) {
            string resultMessage = "The position was successfully deleted.";
            Position positionToDelete = positionRepository.Get(id);

            if (positionToDelete != null) {
                positionRepository.Delete(positionToDelete);

                try {
                    positionRepository.DbContext.CommitChanges();
                }
                catch {
                    resultMessage = "A problem was encountered preventing the position from being deleted. " +
						"Another item likely depends on this position.";
                    positionRepository.DbContext.RollbackTransaction();
                }
            }
            else {
                resultMessage = "The position could not be found for deletion. It may already have been deleted.";
            }

            TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = resultMessage;
            return RedirectToAction("Index");
        }

		/// <summary>
		/// Holds data to be passed to the Position form for creates and edits
		/// </summary>
        public class PositionFormViewModel
        {
            private PositionFormViewModel() { }

			/// <summary>
			/// Creation method for creating the view model. Services may be passed to the creation 
			/// method to instantiate items such as lists for drop down boxes.
			/// </summary>
            public static PositionFormViewModel CreatePositionFormViewModel(
                IRepository<JobTitle> jobTitlesRepository,
                IRepository<Client> clinetRepository)
            {
                return new PositionFormViewModel {
                    Titles = jobTitlesRepository.GetAll(),
                    Clients = clinetRepository.GetAll(),
                    Durations = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }
                };
            }

            public Position Position { get; internal set; }
            public IList<JobTitle> Titles { get; internal set; }
            public IList<Client> Clients { get; internal set; }
            public int[] Durations { get; internal set; }
        }

        private readonly IRepository<Position> positionRepository;
        private readonly IRepository<JobTitle> jobTitlesRepository;
        private readonly IRepository<Client> clinetRepository;
    }
}
